﻿namespace NMortgage.UI.Model
{
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;

    using FluentValidation;

    public sealed class ExtraPaymentCollectionValidator : AbstractValidator<ExtraPaymentCollection>
    {
        #region Constructors

        public ExtraPaymentCollectionValidator()
        {
            RuleFor(p => p.Count).GreaterThan(0);
            RuleFor(p => p.Count).Must(HaveValidChildren);
        }

        #endregion Constructors

        #region Methods

        public bool HaveValidChildren(ExtraPaymentCollection instance, int e)
        {
            return instance.Count(p =>
            {
                IValidatable vp = p as IValidatable;
                return ((vp != null && !vp.IsValid) ? true : false);
            }) == 0;
        }

        #endregion Methods
    }

    public sealed class ExtraPaymentValidator : AbstractValidator<ExtraPayment>
    {
        #region Fields

        private const int MAX_YEARS = 12;
        private const int MONTHS_IN_YEAR = 12;

        #endregion Fields

        #region Constructors

        public ExtraPaymentValidator()
        {
            RuleFor(r => r.Amount)
                .GreaterThan(0);

            RuleFor(r => r.OffsetMonths)
                .GreaterThanOrEqualTo(0)
                .LessThanOrEqualTo(MONTHS_IN_YEAR);

            RuleFor(r => r.OffsetYears)
                .GreaterThanOrEqualTo(0)
                .LessThanOrEqualTo(MAX_YEARS);

            RuleFor(r => r.Frequency)
                .Must(HaveFrequencyForRecurringType)
                .WithMessage("You must enter a frequency for recurring types.");

            RuleFor(r => r.Years)
                .Must(HaveDurationForRecurringType)
                .WithMessage("You must enter a duration for recurring types.");
            RuleFor(r => r.Months)
                .Must(HaveDurationForRecurringType)
                .WithMessage("You must enter a duration for recurring types.");
        }

        #endregion Constructors

        #region Methods
        private bool HaveFrequencyForRecurringType(ExtraPayment instance, int frequency)
        {
            if (instance.Type == ExtraPaymentType.OneTime) { return true; }

            return frequency > 0;
        }

        private bool HaveDurationForRecurringType(ExtraPayment instance, int duration)
        {
            if (instance.Type == ExtraPaymentType.OneTime) { return true; }

            return instance.TotalDurationInMonths > 0;
        }

        private bool HaveYearsMonthsGreaterThanZero(ExtraPayment instance, int i)
        {
            return instance.TotalOffsetInMonths > 0;
        }

        #endregion Methods
    }
}